<?php

namespace app\admin\model\scanwork;

use think\Model;

/**
 * 员工基础数据模型
 */
class Employee extends Model
{
    // 表名
    protected $name = 'scanwork_employee';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    
    // 追加属性
    protected $append = [
        'status_text',
        'skill_level_text'
    ];
    
    // 员工状态
    public function getStatusList()
    {
        return [
            '0' => __('离职'),
            '1' => __('在职')
        ];
    }

    public function getStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
        $list = $this->getStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    // 技能等级
    public function getSkillLevelList()
    {
        return [
            'basic' => __('基础'),
            'intermediate' => __('中级'),
            'advanced' => __('高级')
        ];
    }

    public function getSkillLevelTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['skill_level']) ? $data['skill_level'] : '');
        $list = $this->getSkillLevelList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    // 关联系统用户
    public function user()
    {
        return $this->belongsTo('app\common\model\User', 'user_id', 'id');
    }

    // 关联分工分配
    public function allocations()
    {
        return $this->hasMany('app\admin\model\scanwork\Allocation', 'user_id', 'user_id');
    }

    // 关联报工记录
    public function reports()
    {
        return $this->hasMany('app\admin\model\scanwork\Report', 'user_id', 'user_id');
    }

    // 关联工资核算
    public function wageCalculations()
    {
        return $this->hasMany('app\admin\model\scanwork\WageCalculation', 'employee_id', 'id');
    }

    // 获取员工编码
    public function getEmployeeCodeAttr($value, $data)
    {
        if (empty($value) && isset($data['id'])) {
            $value = 'RY-' . date('Y') . '-' . str_pad($data['id'], 3, '0', STR_PAD_LEFT);
        }
        return $value;
    }

    // 检查员工编码是否唯一
    public function checkCodeUnique($code, $id = null)
    {
        $where = ['employee_code' => $code];
        if ($id) {
            $where['id'] = ['<>', $id];
        }
        return $this->where($where)->count() == 0;
    }

    // 检查用户ID是否唯一
    public function checkUserIdUnique($userId, $id = null)
    {
        $where = ['user_id' => $userId];
        if ($id) {
            $where['id'] = ['<>', $id];
        }
        return $this->where($where)->count() == 0;
    }

    // 获取可操作工序列表
    public function getOperableProcessesAttr($value, $data)
    {
        if (is_string($value)) {
            return json_decode($value, true) ?: [];
        }
        return $value ?: [];
    }

    // 设置可操作工序
    public function setOperableProcessesAttr($value, $data)
    {
        if (is_array($value)) {
            return json_encode($value, JSON_UNESCAPED_UNICODE);
        }
        return $value;
    }

    // 获取员工工作量统计
    public function getWorkloadStats($startDate = null, $endDate = null)
    {
        $where = ['user_id' => $this->user_id];
        
        if ($startDate) {
            $where['createtime'] = ['>=', strtotime($startDate)];
        }
        if ($endDate) {
            $where['createtime'] = ['<=', strtotime($endDate . ' 23:59:59')];
        }

        $allocations = $this->allocations()->where($where)->select();
        $reports = $this->reports()->where($where)->where('status', 1)->select();

        $totalAllocated = 0;
        $totalReported = 0;
        $totalHours = 0;
        $totalWage = 0;

        if ($allocations && count($allocations) > 0) {
            foreach ($allocations as $allocation) {
                $totalAllocated += $allocation->quantity;
                $totalHours += $allocation->actual_hours;
            }
        }

        if ($reports && count($reports) > 0) {
            foreach ($reports as $report) {
                $totalReported += $report->quantity;
                $totalWage += $report->wage;
            }
        }

        return [
            'total_allocated' => $totalAllocated,
            'total_reported' => $totalReported,
            'completion_rate' => $totalAllocated > 0 ? round($totalReported / $totalAllocated * 100, 2) : 0,
            'total_hours' => $totalHours,
            'total_wage' => $totalWage,
            'allocation_count' => count($allocations),
            'report_count' => count($reports)
        ];
    }

    // 获取员工技能匹配的工序
    public function getMatchingProcesses()
    {
        $operableProcesses = $this->operable_processes;
        if (empty($operableProcesses)) {
            return [];
        }

        $processes = \app\admin\model\scanwork\Process::where('id', 'in', $operableProcesses)
            ->where('status', 1)
            ->select();

        return $processes;
    }

    // 检查员工是否可以操作指定工序
    public function canOperateProcess($processId)
    {
        $operableProcesses = $this->operable_processes;
        return in_array($processId, $operableProcesses);
    }

    // 获取员工当前工作负荷
    public function getCurrentWorkload()
    {
        try {
            $currentAllocations = $this->allocations()
                ->where('status', 0)
                ->where('quantity', '>', 'reported_quantity')
                ->select();

            $totalRemaining = 0;
            if ($currentAllocations && count($currentAllocations) > 0) {
                foreach ($currentAllocations as $allocation) {
                    $totalRemaining += ($allocation->quantity - $allocation->reported_quantity);
                }
            }

            return [
                'current_tasks' => $currentAllocations ? count($currentAllocations) : 0,
                'remaining_quantity' => $totalRemaining,
                'allocations' => $currentAllocations ?: []
            ];
        } catch (Exception $e) {
            return [
                'current_tasks' => 0,
                'remaining_quantity' => 0,
                'allocations' => []
            ];
        }
    }

    // 获取员工工资统计
    public function getWageStats($startDate = null, $endDate = null)
    {
        $where = ['employee_id' => $this->id];
        
        if ($startDate) {
            $where['calculation_date'] = ['>=', $startDate];
        }
        if ($endDate) {
            $where['calculation_date'] = ['<=', $endDate];
        }

        $wageCalculations = $this->wageCalculations()->where($where)->select();

        $totalWage = 0;
        $totalPieceWage = 0;
        $totalTimeWage = 0;
        $totalOvertimeWage = 0;

        if ($wageCalculations && count($wageCalculations) > 0) {
            foreach ($wageCalculations as $wage) {
                $totalWage += $wage->total_wage;
                $totalPieceWage += $wage->piece_wage;
                $totalTimeWage += $wage->time_wage;
                $totalOvertimeWage += $wage->overtime_wage;
            }
        }

        return [
            'total_wage' => $totalWage,
            'total_piece_wage' => $totalPieceWage,
            'total_time_wage' => $totalTimeWage,
            'total_overtime_wage' => $totalOvertimeWage,
            'calculation_count' => count($wageCalculations)
        ];
    }

    // 更新员工技能等级
    public function updateSkillLevel($newLevel)
    {
        $validLevels = array_keys($this->getSkillLevelList());
        if (!in_array($newLevel, $validLevels)) {
            throw new \Exception('无效的技能等级');
        }

        $this->save(['skill_level' => $newLevel]);
    }

    // 添加可操作工序
    public function addOperableProcess($processId)
    {
        $operableProcesses = $this->operable_processes;
        if (!in_array($processId, $operableProcesses)) {
            $operableProcesses[] = $processId;
            $this->save(['operable_processes' => $operableProcesses]);
        }
    }

    // 移除可操作工序
    public function removeOperableProcess($processId)
    {
        $operableProcesses = $this->operable_processes;
        $key = array_search($processId, $operableProcesses);
        if ($key !== false) {
            unset($operableProcesses[$key]);
            $this->save(['operable_processes' => array_values($operableProcesses)]);
        }
    }
}
